/**
 * Python环境检查服务
 * 提供Python环境检查、安装状态监控和UI提示功能
 * 可供多个插件调用
 */

import { BrowserWindow, ipcMain, dialog } from 'electron';
import * as childProcess from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
import * as https from 'https';
import * as http from 'http';

export interface PythonEnvironmentResult {
  success: boolean;
  pythonInstalled: boolean;
  pythonVersion?: string;
  pipInstalled?: boolean;
  error?: string;
  requiresManualInstall?: boolean;
}

export interface PythonEnvironmentStatus {
  type: 'info' | 'success' | 'error' | 'warning';
  message: string;
  progress?: number;
  autoClose?: boolean;
}

export class PythonEnvironmentService {
  private static instance: PythonEnvironmentService;
  private mainWindow: BrowserWindow | null = null;
  private ipcHandlersSetup: boolean = false; // 添加标志防止重复注册
  private environmentCache: {
    result: PythonEnvironmentResult | null;
    timestamp: number;
    pythonPath: string | null;
    pathTimestamp: number;
  } = {
    result: null,
    timestamp: 0,
    pythonPath: null,
    pathTimestamp: 0
  };
  private readonly CACHE_DURATION = 30000; // 30秒缓存
  private readonly PATH_CACHE_DURATION = 60000; // 60秒路径缓存

  private constructor() {
    this.setupIpcHandlers();
  }

  public static getInstance(): PythonEnvironmentService {
    if (!PythonEnvironmentService.instance) {
      PythonEnvironmentService.instance = new PythonEnvironmentService();
    }
    return PythonEnvironmentService.instance;
  }

  public setMainWindow(window: BrowserWindow) {
    this.mainWindow = window;
  }

  public setupIpcHandlers() {
    // 防止重复注册IPC处理器
    if (this.ipcHandlersSetup) {
      console.log('Python IPC handlers already setup, skipping...');
      return;
    }

    // Python环境检查处理器
    ipcMain.handle('check-python-environment', async () => {
      return await this.checkPythonEnvironment();
    });

    // Python环境状态更新处理器
    ipcMain.handle('update-python-environment-status', (event, status: PythonEnvironmentStatus) => {
      this.broadcastPythonStatus(status);
    });
    
    // 为插件提供Python环境检查接口
    ipcMain.handle('plugin-check-python-environment', async (event, pluginName: string) => {
      return await this.checkPythonForPlugin(pluginName);
    });

    // 下载并安装Python
    ipcMain.handle('download-and-install-python', async (event) => {
      return await this.downloadAndInstallPython(event);
    });

    // 检查并下载Python环境（整合功能）
    ipcMain.handle('check-and-download-python-environment', async (event, pluginName: string) => {
      return await this.checkAndDownloadPythonEnvironment(pluginName);
    });

    // 清除Python环境缓存
    ipcMain.handle('clear-python-environment-cache', async () => {
      this.clearCache();
      return { success: true, message: 'Python环境缓存已清除' };
    });

    // 标记IPC处理器已设置
    this.ipcHandlersSetup = true;
    console.log('Python IPC handlers setup completed');
  }

  /**
   * 检查缓存是否有效
   */
  private isCacheValid(): boolean {
    const now = Date.now();
    return this.environmentCache.result !== null && 
           (now - this.environmentCache.timestamp) < this.CACHE_DURATION;
  }

  /**
   * 检查路径缓存是否有效
   */
  private isPathCacheValid(): boolean {
    const now = Date.now();
    return this.environmentCache.pythonPath !== null && 
           (now - this.environmentCache.pathTimestamp) < this.PATH_CACHE_DURATION;
  }

  /**
   * 清除缓存
   */
  public clearCache(): void {
    this.environmentCache.result = null;
    this.environmentCache.timestamp = 0;
    this.environmentCache.pythonPath = null;
    this.environmentCache.pathTimestamp = 0;
    console.log('Python环境缓存已清除');
  }

  /**
   * 检查Python环境安装状态
   */
  public async checkPythonEnvironment(): Promise<PythonEnvironmentResult> {
    // 检查缓存
    if (this.isCacheValid()) {
      console.log('使用缓存的Python环境检查结果');
      return this.environmentCache.result!;
    }

    try {
      console.log('开始检查Python环境...');
      this.broadcastPythonStatus({
        type: 'info',
        message: '正在检查Python环境...'
      });

      const pythonCheck = await this.checkPythonInstallation();
      
      if (pythonCheck.installed && pythonCheck.pipInstalled) {
        console.log(`Python环境检查完成 - 版本: ${pythonCheck.version}`);
        this.broadcastPythonStatus({
          type: 'success',
          message: `Python已安装 (版本: ${pythonCheck.version})`,
          autoClose: true
        });
        
        const result = {
          success: true,
          pythonInstalled: true,
          pythonVersion: pythonCheck.version,
          pipInstalled: pythonCheck.pipInstalled
        };
        
        // 缓存结果
        this.environmentCache.result = result;
        this.environmentCache.timestamp = Date.now();
        
        return result;
      } else if (pythonCheck.installed && !pythonCheck.pipInstalled) {
        const errorMsg = 'Python已安装但pip不可用，请重新安装Python并确保包含pip';
        console.log(errorMsg);
        this.broadcastPythonStatus({
          type: 'error',
          message: errorMsg
        });
        
        const result = {
          success: false,
          pythonInstalled: true,
          pythonVersion: pythonCheck.version,
          pipInstalled: false,
          error: errorMsg
        };
        
        // 缓存结果（即使是错误结果也缓存，避免重复检查）
        this.environmentCache.result = result;
        this.environmentCache.timestamp = Date.now();
        
        return result;
      } else {
        console.log('Python未安装');
        this.broadcastPythonStatus({
          type: 'warning',
          message: 'Python未安装，正在准备下载安装包...'
        });
        
        // 尝试自动下载Python安装包
        try {
          const downloadResult = await this.downloadAndInstallPython();
          if (downloadResult.success) {
            const result = {
              success: false,
              pythonInstalled: false,
              error: downloadResult.error || 'Python安装包已下载，请手动安装',
              requiresManualInstall: true
            };
            
            // 不缓存需要手动安装的结果
            return result;
          } else {
            return {
              success: false,
              pythonInstalled: false,
              error: downloadResult.error || 'Python下载失败',
              requiresManualInstall: true
            };
          }
        } catch (downloadError) {
          console.error('Python下载过程出错:', downloadError);
          this.broadcastPythonStatus({
            type: 'error',
            message: `Python下载失败: ${downloadError instanceof Error ? downloadError.message : String(downloadError)}`
          });
          
          return {
            success: false,
            pythonInstalled: false,
            error: `Python下载失败: ${downloadError instanceof Error ? downloadError.message : String(downloadError)}`,
            requiresManualInstall: true
          };
        }
      }
    } catch (error) {
      const errorMsg = `Python环境检查出错: ${error instanceof Error ? error.message : String(error)}`;
      console.error(errorMsg);
      this.broadcastPythonStatus({
        type: 'error',
        message: errorMsg
      });
      
      return {
        success: false,
        pythonInstalled: false,
        error: errorMsg
      };
    }
  }

  /**
   * 检查Python安装状态（复用main.ts中的逻辑）
   */
  private async checkPythonInstallation(): Promise<{
    installed: boolean;
    version?: string;
    pipInstalled?: boolean;
  }> {
    return new Promise(async (resolve) => {
      const tryPythonCommand = async (command: string): Promise<{
        success: boolean;
        version?: string;
        pipInstalled?: boolean;
      }> => {
        return new Promise((cmdResolve) => {
          console.log(`尝试Python命令: ${command}`);
          const pythonProcess = childProcess.spawn(command, ['--version'], {
            stdio: ['pipe', 'pipe', 'pipe'],
            shell: true
          });
          
          let output = '';
          let errorOutput = '';
          
          pythonProcess.stdout.on('data', (data) => {
            output += data.toString();
          });
          
          pythonProcess.stderr.on('data', (data) => {
            errorOutput += data.toString();
          });
          
          pythonProcess.on('close', (code) => {
            console.log(`Python命令 ${command} 退出码: ${code}`);
            
            if (code === 0) {
              console.log(`Python版本输出: ${output.trim()}`);
              if (errorOutput.trim()) {
                console.log(`附加输出: ${errorOutput.trim()}`);
              }
              
              const versionMatch = (output + errorOutput).match(/Python (\d+\.\d+\.\d+)/);
              const version = versionMatch ? versionMatch[1] : 'Unknown';
              console.log(`检测到Python版本: ${version}`);
              
              // 检查pip
              const pipProcess = childProcess.spawn(command, ['-m', 'pip', '--version'], {
                stdio: ['pipe', 'pipe', 'pipe'],
                shell: true
              });
              
              pipProcess.on('close', (pipCode) => {
                console.log(`pip检查退出码: ${pipCode}`);
                cmdResolve({ success: true, version, pipInstalled: pipCode === 0 });
              });
              
              pipProcess.on('error', () => {
                console.log('pip检查出错');
                cmdResolve({ success: true, version, pipInstalled: false });
              });
            } else {
              // 只有在命令失败时才输出错误信息
              if (output.trim()) {
                console.log(`命令输出: ${output.trim()}`);
              }
              if (errorOutput.trim()) {
                console.log(`错误输出: ${errorOutput.trim()}`);
              }
              cmdResolve({ success: false });
            }
          });
          
          pythonProcess.on('error', () => {
            cmdResolve({ success: false });
          });
        });
      };
      
      // 尝试常见的Python命令
      const pythonCommands = ['python', 'python3'];
      
      for (const cmd of pythonCommands) {
        const result = await tryPythonCommand(cmd);
        if (result.success) {
          resolve({ installed: true, version: result.version, pipInstalled: result.pipInstalled });
          return;
        }
      }
      
      // 如果PATH中没有找到，检查常见的安装路径
      const commonPaths = [
        // Windows用户目录安装路径
        path.join(os.homedir(), 'AppData', 'Local', 'Programs', 'Python', 'Python312', 'python.exe'),
        // 系统级安装路径
        'C:\\Program Files\\Python\\Python312\\python.exe',
        'C:\\Program Files\\Python312\\python.exe',
        'C:\\Program Files (x86)\\Python312\\python.exe',
      ];
      
      for (const pythonPath of commonPaths) {
        try {
          if (fs.existsSync(pythonPath)) {
            console.log(`找到Python安装路径: ${pythonPath}`);
            const result = await tryPythonCommand(pythonPath);
            if (result.success) {
              resolve({ installed: true, version: result.version, pipInstalled: result.pipInstalled });
              return;
            }
          }
        } catch (error) {
          console.log(`检查路径 ${pythonPath} 时出错:`, error);
          continue;
        }
      }
      
      console.log('未找到Python安装');
      resolve({ installed: false });
    });
  }

  /**
   * 向所有渲染进程广播Python状态更新
   */
  private broadcastPythonStatus(status: PythonEnvironmentStatus) {
    if (this.mainWindow && !this.mainWindow.isDestroyed()) {
      this.mainWindow.webContents.send('python-environment-status', status);
    }
  }

  /**
   * 显示Python环境状态提示
   */
  public async showPythonEnvironmentAlert(type: 'info' | 'success' | 'error' | 'warning', message: string, autoClose: boolean = true): Promise<void> {
    if (this.mainWindow && !this.mainWindow.isDestroyed()) {
      this.mainWindow.webContents.send('show-python-environment-alert', {
        type,
        message,
        autoClose
      });
    }
  }

  /**
   * 更新Python环境状态提示
   */
  public async updatePythonEnvironmentAlert(type: 'info' | 'success' | 'error' | 'warning', message: string, progress?: number): Promise<void> {
    if (this.mainWindow && !this.mainWindow.isDestroyed()) {
      this.mainWindow.webContents.send('update-python-environment-alert', {
        type,
        message,
        progress
      });
    }
  }

  /**
   * 为特定插件检查Python环境
   * 返回格式与sofaData-process.js中期望的格式一致
   */
  public async checkPythonForPlugin(pluginName: string): Promise<any> {
    console.log(`为插件 ${pluginName} 检查Python环境`);
    
    try {
      const result = await this.checkPythonEnvironment();
      
      // 转换为插件期望的格式
      if (result.success && result.pythonInstalled) {
        return {
          installed: true,
          version: result.pythonVersion || 'Unknown',
          pipInstalled: result.pipInstalled || false,
          success: true,
          message: `Python已安装 (版本: ${result.pythonVersion || 'Unknown'})`
        };
      } else {
        return {
          installed: false,
          version: null,
          pipInstalled: false,
          success: false,
          message: result.error || 'Python未安装或检查失败'
        };
      }
    } catch (error) {
      console.error(`插件 ${pluginName} Python环境检查出错:`, error);
      return {
        installed: false,
        version: null,
        pipInstalled: false,
        success: false,
        message: `Python环境检查出错: ${error instanceof Error ? error.message : String(error)}`
      };
    }
  }

  /**
   * 下载文件
   */
  private downloadFile(url: string, dest: string, event?: any): Promise<void> {
    return new Promise((resolve, reject) => {
      const file = fs.createWriteStream(dest);
      const protocol = url.startsWith('https:') ? https : http;
      
      const request = protocol.get(url, (response) => {
        if (response.statusCode === 302 || response.statusCode === 301) {
          // 处理重定向
          file.close();
          try {
            fs.unlinkSync(dest);
          } catch (e) {
            // 忽略删除文件错误
          }
          this.downloadFile(response.headers.location!, dest, event)
            .then(resolve)
            .catch(reject);
          return;
        }
        
        if (response.statusCode !== 200) {
          file.close();
          try {
            fs.unlinkSync(dest);
          } catch (e) {
            // 忽略删除文件错误
          }
          reject(new Error(`下载失败，状态码: ${response.statusCode}`));
          return;
        }
        
        const totalSize = parseInt(response.headers['content-length'] || '0', 10);
        let downloadedSize = 0;
        
        response.pipe(file);
        
        response.on('data', (chunk) => {
          downloadedSize += chunk.length;
          if (totalSize > 0 && event) {
            const progress = Math.round((downloadedSize / totalSize) * 100);
            this.broadcastPythonStatus({
              type: 'info',
              message: `正在下载Python安装包... ${progress}%`,
              progress
            });
          }
        });
        
        file.on('finish', () => {
          file.close();
          resolve();
        });
      });
      
      request.on('error', (err) => {
        file.close();
        if (fs.existsSync(dest)) {
          fs.unlinkSync(dest);
        }
        reject(err);
      });
      
      file.on('error', (err) => {
        file.close();
        if (fs.existsSync(dest)) {
          fs.unlinkSync(dest);
        }
        reject(err);
      });
    });
  }

  /**
   * 下载并安装Python
   */
  public async downloadAndInstallPython(event?: any): Promise<PythonEnvironmentResult> {
    try {
      this.broadcastPythonStatus({
        type: 'info',
        message: '正在准备下载Python...'
      });

      // 确定下载URL和文件名
       const pythonVersion = '3.12.3';
       const isWindows = os.platform() === 'win32';
       const arch = os.arch() === 'x64' ? 'amd64' : 'win32';
       
       if (!isWindows) {
         throw new Error('当前仅支持Windows系统的自动安装');
       }
       
       const fileName = `python-${pythonVersion}-${arch}.exe`;
       // 使用内网下载源，更稳定
       const downloadUrl = arch === 'amd64' 
         ? 'http://10.169.128.20/files/python/python-3.12.3-amd64.exe'
         : 'http://10.169.128.20/files/python/python-3.12.3.exe';
       const desktopPath = path.join(os.homedir(), 'Desktop');
       const installerPath = path.join(desktopPath, fileName);
      
      console.log(`开始下载Python ${pythonVersion}`);
      console.log(`下载URL: ${downloadUrl}`);
      console.log(`保存路径: ${installerPath}`);
      
      // 下载Python安装包
       await this.downloadFile(downloadUrl, installerPath, event);
       
       this.broadcastPythonStatus({
         type: 'success',
         message: 'Python安装包下载完成！'
       });
       
       // 下载完成后等待文件系统释放句柄
       console.log('下载完成，等待文件系统释放句柄...');
       await new Promise(resolve => setTimeout(resolve, 1000));
       
       console.log(`Python安装包已下载到桌面: ${installerPath}`);
       
       // 显示弹框提醒用户手动安装
       const result = await dialog.showMessageBox({
         type: 'info',
         title: 'Python安装包下载完成',
         message: 'Python安装包已下载到桌面',
         detail: `请手动运行安装程序：${fileName}\n\n安装时请确保勾选以下选项：\n- Add Python to PATH\n然后点击Install Now\n\n安装完成后请重新检查Python环境。`,
         buttons: ['确定']
       });
       
       // 用户点击确定后最小化所有窗口
       if (result.response === 0) {
         const allWindows = BrowserWindow.getAllWindows();
         allWindows.forEach(window => {
           if (window && !window.isDestroyed()) {
             window.minimize();
           }
         });
       }
       
       this.broadcastPythonStatus({
         type: 'info',
         message: `Python安装包已下载到桌面，请手动运行安装程序：${fileName}`,
         autoClose: false
       });
       
       return {
         success: true,
         pythonInstalled: false,
         requiresManualInstall: true,
         error: `请手动运行桌面上的 ${fileName} 进行安装`
       };
      
    } catch (error) {
      const errorMsg = `Python下载安装失败: ${error instanceof Error ? error.message : String(error)}`;
      console.error(errorMsg);
      this.broadcastPythonStatus({
        type: 'error',
        message: errorMsg
      });
      
      return {
        success: false,
        pythonInstalled: false,
        error: errorMsg
      };
    }
  }

  /**
   * 检查并下载Python环境（用于插件调用）/**
   * 获取Python可执行文件路径
   */
  public async getPythonExecutablePath(): Promise<string | null> {
    // 检查路径缓存
    if (this.isPathCacheValid()) {
      console.log('使用缓存的Python路径:', this.environmentCache.pythonPath);
      return this.environmentCache.pythonPath;
    }

    return new Promise(async (resolve) => {
      const tryPythonCommand = async (command: string): Promise<boolean> => {
        return new Promise((cmdResolve) => {
          const pythonProcess = childProcess.spawn(command, ['--version'], {
            stdio: ['pipe', 'pipe', 'pipe'],
            shell: true
          });
          
          pythonProcess.on('close', (code) => {
            cmdResolve(code === 0);
          });
          
          pythonProcess.on('error', () => {
            cmdResolve(false);
          });
        });
      };
      
      // 尝试常见的Python命令
      const pythonCommands = ['python', 'python3'];
      
      for (const cmd of pythonCommands) {
        const result = await tryPythonCommand(cmd);
        if (result) {
          // 缓存找到的路径
          this.environmentCache.pythonPath = cmd;
          this.environmentCache.pathTimestamp = Date.now();
          console.log('找到并缓存Python路径:', cmd);
          resolve(cmd);
          return;
        }
      }
      
      // 如果PATH中没有找到，检查常见的安装路径
      const commonPaths = [
        // Windows用户目录安装路径
        path.join(os.homedir(), 'AppData', 'Local', 'Programs', 'Python', 'Python312', 'python.exe'),
        // 系统级安装路径
        'C:\\Program Files\\Python312\\python.exe',
        'C:\\Program Files (x86)\\Python312\\python.exe',
      ];
      
      for (const pythonPath of commonPaths) {
        try {
          if (fs.existsSync(pythonPath)) {
            const result = await tryPythonCommand(pythonPath);
            if (result) {
              // 缓存找到的路径
              this.environmentCache.pythonPath = pythonPath;
              this.environmentCache.pathTimestamp = Date.now();
              console.log('找到并缓存Python路径:', pythonPath);
              resolve(pythonPath);
              return;
            }
          }
        } catch (error) {
          continue;
        }
      }
      
      resolve(null);
    });
  }

  /**
   * 整合功能：检查并下载Python环境
   */
  public async checkAndDownloadPythonEnvironment(pluginName: string): Promise<any> {
    console.log(`为插件 ${pluginName} 检查并下载Python环境`);
    
    try {
      // 显示检查状态
      await this.showPythonEnvironmentAlert('info', '正在检查Python环境...');
      
      const result = await this.checkPythonEnvironment();
      
      if (result.success && result.pythonInstalled) {
        // Python已安装且可用
        const pipStatus = result.pipInstalled ? '已安装' : '未安装';
        const message = `Python已安装 (版本: ${result.pythonVersion || 'Unknown'}, pip: ${pipStatus})`;
        
        await this.showPythonEnvironmentAlert('success', message, true);
        
        return {
          installed: true,
          version: result.pythonVersion || 'Unknown',
          pipInstalled: result.pipInstalled || false,
          success: true,
          message: message
        };
      } else {
        // Python未安装或不可用，显示错误信息
        const errorMessage = result.error || 'Python未安装或检查失败';
        await this.showPythonEnvironmentAlert('error', errorMessage);
        
        return {
          installed: false,
          version: null,
          pipInstalled: false,
          success: false,
          message: errorMessage
        };
      }
    } catch (error) {
      const errorMsg = `Python环境检查出错: ${error instanceof Error ? error.message : String(error)}`;
      console.error(`插件 ${pluginName} Python环境检查出错:`, error);
      
      await this.showPythonEnvironmentAlert('error', errorMsg);
      
      return {
        installed: false,
        version: null,
        pipInstalled: false,
        success: false,
        message: errorMsg
      };
    }
  }

  /**
   * 安装Python
   */
  private installPython(installerPath: string): Promise<{ success: boolean; error?: string }> {
    return new Promise((resolve) => {
      console.log(`开始安装Python: ${installerPath}`);
      
      // 使用静默安装参数
      const installArgs = [
        '/quiet',
        'InstallAllUsers=0',  // 为当前用户安装
        'PrependPath=1',      // 添加到PATH
        'Include_test=0',     // 不包含测试
        'Include_pip=1',      // 包含pip
        'Include_tcltk=1',    // 包含tkinter
        'Include_launcher=1', // 包含启动器
        'AssociateFiles=1'    // 关联文件
      ];
      
      const installProcess = childProcess.spawn(installerPath, installArgs, {
        stdio: ['pipe', 'pipe', 'pipe'],
        shell: true
      });
      
      let output = '';
      let errorOutput = '';
      
      installProcess.stdout.on('data', (data) => {
        output += data.toString();
        console.log('安装输出:', data.toString());
      });
      
      installProcess.stderr.on('data', (data) => {
        errorOutput += data.toString();
        console.log('安装错误输出:', data.toString());
      });
      
      installProcess.on('close', (code) => {
        console.log(`Python安装进程退出，退出码: ${code}`);
        console.log('安装输出:', output);
        console.log('错误输出:', errorOutput);
        
        if (code === 0) {
          resolve({ success: true });
        } else {
          resolve({ 
            success: false, 
            error: `安装失败，退出码: ${code}. 错误信息: ${errorOutput}` 
          });
        }
      });
      
      installProcess.on('error', (error) => {
        console.error('安装进程错误:', error);
        resolve({ 
          success: false, 
          error: `安装进程启动失败: ${error.message}` 
        });
      });
    });
  }
}

// 导出单例实例
export const pythonEnvironmentService = PythonEnvironmentService.getInstance();